package controller

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisService"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/httpserver"
	"strings"
	"time"
)

type deviceValueExManageController struct {
}

func (e *deviceValueExManageController) init() {
	httpserver.Server.POST("/device/value/ex/page", e.selectPageList)
}

func (e *deviceValueExManageController) selectPageList(context httpserver.Context, body map[string]interface{}) (interface{}, error) {
	// 提取业务参数
	deviceName := Map.GetString(body, "deviceName", "")
	objectName := Map.GetString(body, "objectName", "")
	pageNum := Map.GetInt(body, "pageNum", 1)
	pageSize := Map.GetInt(body, "pageSize", 10)

	// 简单校验参数
	if Map.HasNull(body, "pageNum", "pageSize") {
		return nil, errors.New("参数不能为空:pageNum, pageSize")
	}

	entityList := make([]commEntity.IEntity, 0)
	if !Method.HasEmpty(deviceName) {
		entity := edgeEntity.Type.DeviceValueExEntity.Instance()
		entity.DeviceName = deviceName

		exist, err := commRedisService.GetEntityByServiceKey(entity.Type(), entity.MakeServiceKey())
		if err != nil {
			return nil, err
		}
		if exist != nil {
			entityList = append(entityList, exist)
		}
	} else {
		list, err := commRedisService.GetEntityList(edgeEntity.Type.DeviceValueExEntity.Type())
		if err != nil {
			return nil, err
		}
		if list != nil {
			entityList = list
		}
	}

	// 根据ID排序
	commEntity.SortEntityList(entityList)

	// 筛选数据
	entityList = e.selectList(entityList, body)

	// 分页
	total, list := e.getPage(entityList, objectName, pageNum, pageSize)

	result := make(map[string]interface{})
	result["total"] = total
	result["list"] = list
	return result, nil

}

func (e *deviceValueExManageController) selectList(entityList []commEntity.IEntity, body map[string]interface{}) []commEntity.IEntity {
	resultList := make([]commEntity.IEntity, 0)
	for _, v := range entityList {
		entity := v.(*edgeEntity.DeviceValueExEntity)

		result := true

		if Map.Has(body, "manufacturer") {
			result = result && strings.Count(entity.Manufacturer, body["manufacturer"].(string)) > 0
		}
		if Map.Has(body, "deviceType") {
			result = result && strings.Count(entity.Manufacturer, body["deviceType"].(string)) > 0
		}
		if Map.Has(body, "deviceName") {
			result = result && strings.Count(entity.Manufacturer, body["deviceName"].(string)) > 0
		}

		resultList = append(resultList, entity)

	}

	return resultList
}

func (e *deviceValueExManageController) getPage(entityList []commEntity.IEntity, objectName string, pageNmu int, pageSize int) (int, []map[string]interface{}) {
	total := 0
	for _, v := range entityList {
		entity := v.(*edgeEntity.DeviceValueExEntity)
		if entity.Params == nil {
			continue
		}

		// 检查：是否需要进行对象级别名称的过滤
		if !Method.HasEmpty(objectName) {
			_, ok := entity.Params[objectName]
			if ok {
				total += 1
			} else {
				total += len(entity.Params)
			}

			continue
		}

		total += len(entity.Params)
	}

	now := time.Now().UnixMilli()
	list := make([]map[string]interface{}, 0)

	index := 0
	for _, v := range entityList {
		entity := v.(*edgeEntity.DeviceValueExEntity)
		if entity.Params == nil {
			continue
		}

		if (index + len(entity.Params)) <= (pageNmu-1)*pageSize {
			index += len(entity.Params)
			continue
		}

		for key, value := range entity.Params {
			index += 1

			if index <= (pageNmu-1)*pageSize {
				continue
			}

			if len(list) >= pageSize {
				return total, list
			}

			if value == nil {
				continue
			}

			// 检查：是否需要进行对象级别名称的过滤
			if !Method.HasEmpty(objectName) && key != (objectName) {
				continue
			}

			data := make(map[string]interface{})
			data["deviceName"] = entity.DeviceName
			data["deviceType"] = entity.DeviceType
			data["manufacturer"] = entity.Manufacturer
			data["updateTime"] = entity.GetBaseEntity().UpdateTime
			data["id"] = entity.GetBaseEntity().Id
			data["objectName"] = key
			data["objectTime"] = (now - value.Time) / 1000
			data["objectValue"] = value.Value

			list = append(list, data)
		}
	}

	return total, list
}
